package com.heima.wemedia.service.impl;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.feign.ApArticleFeign;
import com.heima.common.dtos.AppHttpCodeEnum;
import com.heima.common.dtos.PageResponseResult;
import com.heima.common.dtos.ResponseResult;
import com.heima.common.exception.LeadNewsException;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.comment.Vo.WmCommentPage;

import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.comment.pojos.ApComment;
import com.heima.model.comment.pojos.ApCommentLike;
import com.heima.model.comment.pojos.ApCommentRepay;
import com.heima.model.wemedia.dtos.WmCommentApplyDto;
import com.heima.model.wemedia.dtos.WmCommentDto;
import com.heima.model.wemedia.dtos.WmCommentPageReqDto;
import com.heima.model.wemedia.dtos.WmCommentStatusDto;



import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.ThreadLocalUtils;
import com.heima.wemedia.mapper.WmCommentMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmCommentService;
import com.mongodb.client.result.DeleteResult;

import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: Xu
 * @Date: 2022/01/03/15:41
 */
@Service

public class WmCommentServiceImpl extends ServiceImpl<WmCommentMapper, ApComment> implements WmCommentService {

    @Autowired
    private  WmCommentMapper wmCommentMapper;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private ApArticleFeign apArticleFeign;

            ;
    /**
     * 评论管理查询  已经作废
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findNewsComment(WmCommentApplyDto dto) {
        //校验传参是否合法
        dto.checkParam();
        //必须追加当前的用户的判断
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        if (wmUser == null){
            //如果无人登录
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据作者的Id查询出所有的文章列表
        //单表：分页+条件+排序
        //条件：（分页+条件+排序）

        /**
         * 分页条件：IPage的封装
         * 条件+排序：QueryWrapper封装
         */
        /**
         * MongoDB聚合函数 对ApComment进行聚合求出评论数量
         */
        //1、调用Feign接口后去当前用户所有的文章列表
        ResponseResult<List<ApArticle>> articleByUserId = apArticleFeign.findArticleByUserId(Long.valueOf(wmUser.getId()));
        List<ApArticle> apArticleList = articleByUserId.getData();
        List<Long> apArticleIdList = apArticleList.stream().map(ApArticle::getId).collect(Collectors.toList());
        //2.聚合函数得出当前用户所有文章的评论对象
//        Aggregation aggregation = Aggregation.newAggregation(
//                Aggregation.project("authorId","entryId","createdTime"),//只需要文章ID  创建时间  count几个字段
//                //id为当前用户
////               Aggregation.match(criteria),
////                Aggregation.match(Criteria.where("authorId").is(4).and("createdTime")
//                Aggregation.match(Criteria.where("entryId").in(apArticleIdList).and("createdTime")
//                        .gte(DateUtils.stringToDate(dto.getBeginDate()))
//                        .lte(DateUtils.stringToDate(dto.getEndDate()))),// 条件大于开始时间  小于结束时间
////                Aggregation.match(Criteria.where("createdTime").gte("2021-06-09 03:44:33.000"),
//                //按照倒序排序
//                Aggregation.group("entryId").count().as("count")// 分组统计  count
//                        .first("createdTime").as("createdTime")//获取createdTime字段
//                        .first("authorId").as("authorId")//评论作者ID
//                        .first("entryId").as("entryId"),//获取
//                //日期降序排列
//                Aggregation.sort(Sort.by(Sort.Direction.DESC,"createdTime")), //根据时间降序
//
//                //分页查询
//                Aggregation.skip(0L),
//                Aggregation.limit(10L)
//
//        );
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.project("authorId","entryId","createdTime"),
                //id为当前用户
//                    Aggregation.match(criteria),
                Aggregation.match(Criteria.where("entryId").in(apArticleIdList)),
                    //todo:时间顺序我做不来了  2022年1月4日10:27:15；许奇伟
//                        .and("createdTime")
//                        .gte(DateUtils.stringToDate("2022-01-01 00:00:00.000"))
//                        .lte(DateUtils.stringToDate("2022-01-04 00:00:00.000"))),// 条件
//                Aggregation.match(Criteria.where("createdTime").gte("2021-06-09 03:44:33.000"),
                //按照倒序排序
                Aggregation.group("entryId").count().as("count")// 分组统计
                        .first("createdTime").as("createdTime")
                        .first("authorId").as("authorId")
                        .first("entryId").as("entryId"),
                //日期降序排列
                Aggregation.sort(Sort.by(Sort.Direction.DESC,"createdTime")),

                //分页查询
                Aggregation.skip(Long.valueOf(dto.getPage()-1)),
                Aggregation.limit(dto.getSize())

        );
        AggregationResults<ApComment> result = mongoTemplate.aggregate(aggregation, "ap_comment",ApComment.class);

        List<ApComment> mappedResultList = result.getMappedResults();
        mappedResultList.forEach(System.out::println);
//        AggregationResults<ApComment> result = mongoTemplate.aggregate(aggregation, "ap_comment",ApComment.class);
//
//        List<ApComment> mappedResultList = result.getMappedResults();
        //判断查处结果是否为空
        if (!CollectionUtils.isNotEmpty(mappedResultList)){
            System.out.println("没有查到数据");
            throw new LeadNewsException(500,"当前条件暂时为空");
        }

//        List<ApComment> collect = mappedResultList.stream().collect(Collectors.toList());
//        mappedResultList.stream().collect(Collectors.toList())
        //调用Feign接口  查询文章ID对应的
        //3.封装对象
            List<WmCommentDto> commentDtos = new ArrayList<>();
        for (ApComment mappedResult : mappedResultList) {
            WmCommentDto wmCommentDto = new WmCommentDto();

            //获取ID
            wmCommentDto.setId(mappedResult.getEntryId());
            //获取标题
            ResponseResult<ApArticle> articleById = apArticleFeign.findArticleById(mappedResult.getEntryId());
            String title = articleById.getData().getTitle();
            wmCommentDto.setTitle(title);
            //获取可以评论的数目
//            wmCommentDto.setComments(mappedResult.getCount());
            //默认可以评论
            wmCommentDto.setIsComment(true);
            //创建时间
            wmCommentDto.setCreatedTime(mappedResult.getCreatedTime().getTime());

            commentDtos.add(wmCommentDto);

        }
        //获取总条数
        int Total = commentDtos.size();

        //将 当前页 、页大小、总条数传入分页返回对象
        PageResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), Total);
        responseResult.setData(commentDtos);
        responseResult.setHost("");
        return  responseResult;
    }

    /**
     * 文章雷彪显示
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findNewsCommentList(WmCommentApplyDto dto) {
        //校验传参是否合法
        dto.checkParam();
        //必须追加当前的用户的判断
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        if (wmUser == null){
            //如果无人登录
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //封装形容DTo
        dto.setAuthorId(Long.valueOf(wmUser.getId()));

        //调用Feign接口




        PageResponseResult articlePage = apArticleFeign.findArticlePage(dto);

        int i = 0;
        return  articlePage;
    }

    /**
     * 修改文章状态
     * @param dto
     * @return
     */
    @Override
    public ResponseResult updateCommentStatus(WmCommentStatusDto dto) {
        //参数校验
        Long articleId = dto.getArticleId();
        Integer operation = dto.getOperation();
        if (articleId==null && operation==null){
            throw new LeadNewsException(444,"无效的请求参数");
        }
        //调用Feign接口修改文章可评论状态
        ResponseResult responseResult = apArticleFeign.updateArticleConfigStatus(dto);
        return  responseResult;

    }

    /**
     * 查看电调文章的评论列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult findCommentList(WmCommentPageReqDto dto) {
/*            //根据分页对象查询 评论；列表
        //检查校验
        dto.checkParam();
        Long articleId = dto.getArticleId();
        Integer page = dto.getPage();
        Integer size = dto.getSize();
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        if (wmUser == null){
            //如果无人登录
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据文章Id查询评论列表
        Query query = new Query(Criteria.where("entryId").is(dto.getArticleId()));
//            query.with(PageRequest.of(page,size));
        List<ApComment> apComments = mongoTemplate.find(query, ApComment.class);
        if (!CollectionUtils.isNotEmpty(apComments)){
            throw new LeadNewsException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        //转换为输出类型
    //    List<ApCommentDto> apCommentDtoList = BeanHelper.copyWithCollection(apComments, ApCommentDto.class);
//            apCommentDtoList.forEach(System.out::println);
        //获取以及评论的ID  使用一级评论查询子评论
        // List<String> commentIdList = apCommentDtoList.stream().map(ApCommentDto::getId).collect(Collectors.toList());
        //根据一级评论目录查找耳机评论
        for (ApComment ApComment : apComments) {
            Query query1 = new Query(Criteria.where("commentId").is(ApComment.getId()));
            List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query1, ApCommentRepay.class);
            //将日期字符串拿出来拿出来 转换日期
            for (ApCommentRepay apCommentRepay : apCommentRepays) {
                ApComment.setApCommentRepays(apCommentRepays);
            }
        }
        int i =0;

        return ResponseResult.okResult(apComments);*/
        /*-----------------------------分割线*/

        //检查校验
   /*     dto.checkParam();
        Long articleId = dto.getArticleId();
        Integer page = dto.getPage();
        Integer size = dto.getSize();
       Long skip= Long.valueOf(size*(page-1)) ;
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        if (wmUser == null){
            //如果无人登录
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据文章Id查询评论列表  分页查询
        Query query = new Query(Criteria.where("entryId").is(dto.getArticleId()))
                .skip(Long.valueOf(size*(page-1)))
                .limit(size);
        //获取初步的分页对象
        List<ApComment> apComments = mongoTemplate.find(query, ApComment.class);
        //将createTime以及UpdateTime设置为integet

        //转换为输出类型
        List<ApCommentDto> apCommentDtoList = BeanHelper.copyWithCollection(apComments, ApCommentDto.class);
        //将createTime由date转换成Long类型  完成封装
        for (ApCommentDto apCommentDto : apCommentDtoList) {
            for (ApComment apComment : apComments) {
                if (apCommentDto.getId().equals(apComment.getId())){
                    Date createdTime = apComment.getCreatedTime();
                    Date updatedTime = apComment.getUpdatedTime();
                    apCommentDto.setCreatedTime(createdTime.getTime());
                    apCommentDto.setUpdatedTime(updatedTime.getTime());
                }
            }
        }
//        apCommentDtoList.forEach(System.out::println);
        //获取以及评论的ID  使用一级评论查询子评论
//            List<String> commentIdList = apCommentDtoList.stream().map(ApCommentDto::getId).collect(Collectors.toList());
        //根据一级评论目录查找耳机评论
        int secondComSize = 0;
        for (ApCommentDto apCommentDto : apCommentDtoList) {
            Query query1 = new Query(Criteria.where("commentId").is(apCommentDto.getId()));
            List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query1, ApCommentRepay.class);
            if (apCommentRepays.size()==0){
                continue;
            }

//            apCommentRepays.forEach(System.out::println);
            //将apCommentRepays 转换为ApCommentRepayDtoA类型
            List<ApCommentRepayDtoA> apCommentRepayDtoAS = BeanHelper.copyWithCollection(apCommentRepays, ApCommentRepayDtoA.class);
            for (ApCommentRepay apCommentRepay : apCommentRepays) {
                for (ApCommentRepayDtoA apCommentRepayDtoA : apCommentRepayDtoAS) {
                    if (apCommentRepay.getId().equals(apCommentRepayDtoA.getId())){
                        Date createdTime = apCommentRepay.getCreatedTime();
                        Date updatedTime = apCommentRepay.getUpdatedTime();
                        apCommentRepayDtoA.setCreatedTime(createdTime.getTime());
                        apCommentRepayDtoA.setUpdatedTime(updatedTime.getTime());
                    }
                }
            }
//            apCommentRepayDtoAS.forEach(System.out::println);

            //将转换为ApCommentRepayDtoA 放入ApCommentDto
            //将日期字符串拿出来拿出来 转换日期
            for (ApCommentRepayDtoA apCommentRepay : apCommentRepayDtoAS) {
                apCommentDto.setApCommentRepays(apCommentRepayDtoAS);
            }

        }
        //当前页对象
        int size2 = 0;
        for (ApCommentDto apCommentDto : apCommentDtoList) {
            if (apCommentDto.getApCommentRepays()!=null){
                size2 = size + apCommentDto.getApCommentRepays().size();
            }
        }

        //自定义一分页独享
        PageResponseResult pageResponseResult = new PageResponseResult(page,size,apCommentDtoList.size()+size2);
        pageResponseResult.setData(apCommentDtoList);
        pageResponseResult.setErrorMessage("成功获取分页");
        apCommentDtoList.forEach(System.out::println);*/

        /*-----------分割线---------------*/

        Long articleId = dto.getArticleId();
        Integer page = dto.getPage();
        Integer size = dto.getSize();
        Long skip= Long.valueOf(size*(page-1)) ;
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();


        if (wmUser == null){
            //如果无人登录
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }
        Integer wmUserId = wmUser.getId();
        LambdaQueryWrapper<WmUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WmUser::getId,wmUserId);
        WmUser user = wmUserMapper.selectOne(wrapper);
        //根据文章Id查询评论列表  分页查询
        Query query = Query.query(Criteria.where("entryId").is(dto.getArticleId()))
                .skip(Long.valueOf(size*(page-1)))
                .limit(size);
        //获取初步的分页对象
        List<ApComment> apComments = mongoTemplate.find(query, ApComment.class);
        //遍历每一条文航评论 将文章评论状态operate是否被当前用户点赞点过赞；
        for (ApComment apComment : apComments) {
            String commentIds = apComment.getId();
            WmUser nowUser = findNowUser();
            Query queryLike = Query.query(Criteria.where("authorId").is(user.getApAuthorId())
                    .and("commentId").is(commentIds));
            ApCommentLike commentLike = mongoTemplate.findOne(queryLike, ApCommentLike.class);
            if (commentLike!=null){
                //设置为点过赞
                apComment.setOperation((short)0);
            }else {
                apComment.setOperation((short)1);

            }
        }


        List<WmCommentPage> wmCommentPageList = new ArrayList<>();
        for (ApComment apComment : apComments) {
            WmCommentPage wmCommentPage = new WmCommentPage();
            //根据评论查询回复
            Query query1 = Query.query(Criteria.where("commentId").is(apComment.getId()));
            List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query1, ApCommentRepay.class);
            wmCommentPage.setApComments(apComment);
            if (apCommentRepays!=null){
                wmCommentPage.setApCommentRepays(apCommentRepays);
            }
            wmCommentPageList.add(wmCommentPage);

        }

//        wmCommentPageList.forEach(System.out::println);

        //自定义一分页独享
        PageResponseResult pageResponseResult = new PageResponseResult(page,size,wmCommentPageList.size());
        pageResponseResult.setData(wmCommentPageList);
        pageResponseResult.setErrorMessage("成功获取分页");
//        apCommentDtoList.forEach(System.out::println);



        return pageResponseResult;
    }

    /**
     * 删除评论
     * @param commentId
     * @return
     */
    @Override
    public ResponseResult deleteComment(String commentId) {
        //判断该评论是否为一级评论
        Query query = Query.query(Criteria.where("id").is(commentId));
        List<ApComment> apComments = mongoTemplate.find(query, ApComment.class);
        //执行判断
        if (!CollectionUtils.isNotEmpty(apComments)){
            //如果一级目录不存在  继续查询二级评论
            List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query, ApCommentRepay.class);
            if (!CollectionUtils.isNotEmpty(apCommentRepays)){
                //如果二级评论也是空  说明二级评论不存在
                throw new LeadNewsException(201,"该评论不存在");
            }
            //如果一级评论为空；二级评论不为空的话、删除二级评论
            DeleteResult remove = mongoTemplate.remove(query, ApCommentRepay.class);
        }else {
            //如果一级评论不为空
            //1.删除一级评论
            DeleteResult remove = mongoTemplate.remove(query, ApComment.class);
            //2.同时删除二级评论
            //2.1查询二级评论
            Query query1 = Query.query(Criteria.where("commentId").is(commentId));
            List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query1, ApCommentRepay.class);
            if (CollectionUtils.isNotEmpty(apCommentRepays)){
                //如果子评论不为空 删除子评论
                mongoTemplate.remove(query1,ApCommentRepay.class);
            }else {
                return  null;
            }
        }
        return ResponseResult.okResult(200,"删除评论成功");
    }

    /**
     * 删除评论回复
     * @param commentRepayId
     * @return
     */
    @Override
    public ResponseResult deleteCommentRepay(String commentRepayId) {
        //参数校验
        if (StringUtils.isEmpty(commentRepayId)){
            throw new LeadNewsException(AppHttpCodeEnum.AD_USER_DATA_NOT_EXIST);
        }
        //构造删除条件
        Query query = Query.query(Criteria.where("id").is(commentRepayId));
        DeleteResult remove = mongoTemplate.remove(query, ApCommentRepay.class);
        long deletedCount = remove.getDeletedCount();
        if (deletedCount==0L){
            throw new LeadNewsException(444,"该评论相关文章已经被删除");
        }
        return ResponseResult.okResult(400,"评论删除成功");
    }
    @Autowired
    private WmUserMapper wmUserMapper;
    /**
     * 评论点赞微服务
     * @param dto
     * @return
     */
    @Override
    public ResponseResult getCommentLike(CommentLikeDto dto) {

        String commentId = dto.getCommentId();
        short operation = dto.getOperation();
        if (commentId == null ){
            throw new LeadNewsException(441,"点赞或取消-失败");
        }
        WmUser nowUser = findNowUser();
        //判断是点赞还是取消点赞
        //是否点过赞
        Query queryLike = Query.query(Criteria.where("authorId").is(nowUser.getApAuthorId())
                .and("commentId").is(dto.getCommentId()));
        ApCommentLike commentLike = mongoTemplate.findOne(queryLike, ApCommentLike.class);

        int i =0;

        if (operation==(short)0){
            if (commentLike != null){
                return ResponseResult.okResult(200,"您已点赞过、重复点赞");
            }
            Query query = Query.query(Criteria.where("id").is(commentId));
            ApComment apComment = mongoTemplate.findOne(query, ApComment.class);
            //点赞数+1
            apComment.setLikes(apComment.getLikes()+1);
            mongoTemplate.save(apComment);
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(nowUser.getApAuthorId());
            apCommentLike.setCommentId(commentId);
            mongoTemplate.save(apCommentLike);
        }else {
            //如果是取消点赞
           if (commentLike == null){
               return  ResponseResult.okResult(200,"尚未点赞，无需取消点赞");
           }
          mongoTemplate.remove(commentLike);
           //点赞列表-1；
            Query query = Query.query(Criteria.where("id").is(commentId));
            ApComment apComment = mongoTemplate.findOne(query, ApComment.class);
            apComment.setLikes(apComment.getLikes()-1);
            mongoTemplate.save(apComment);
        }

        return ResponseResult.okResult(200,"操作成功");
    }

    public WmUser findNowUser(){
        WmUser wmUser = (WmUser) ThreadLocalUtils.get();
        if (wmUser == null){
            throw new LeadNewsException(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据自媒体用户ID 用户对应的作者ID 以及作者姓名
        Integer wmUserId = wmUser.getId();
        LambdaQueryWrapper<WmUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WmUser::getId,wmUserId);
        WmUser user = wmUserMapper.selectOne(wrapper);
        return  user;
    }


}
